import { loginUser, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { resetRouter, anyRoutes, asyncRoutes, constantRoutes } from "@/router";
import router from '@/router'
const getDefaultState = () => {
  return {
    token: getToken(),
    name: "",
    avatar: "",
    routes:[],
    buttons:[],
    roles:[],
    // 对比之后【项目中已有的异步路由,与服务器返回的标记信息进行对比最终需要展示的路由】
    resultAsyncRoutes:[],
    // 用户最终要展示的全部路由
    resultAllRoutes: []
  };
};

const state = getDefaultState();

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_USERINFO: (state, userinfo)=>{
    // 用户名称
    state.name = userinfo.name
    // 用户头像
    state.avatar = userinfo.avatar
    // 菜单权限的标记【根据不同的角色返回的标记信息，数组里面的元素是字符串】
    state.routes = userinfo.routes
    // 按钮权限的标记
    state.buttons = userinfo.buttons
    // 登录之后角色信息
    state.roles = userinfo.roles
  },
  // 最终计算出的异步路由
  SET_RESULTASYNCROUTES:(state, asyncRoutes)=> {
    // vuex保存当前用户的异步路由,注意：一个用户需要展示完成路由包含常量、异步和任意路由
    state.resultAsyncRoutes = asyncRoutes
    // 计算出当前用户要展示的所有路由
   state.resultAllRoutes = constantRoutes.concat(state.resultAsyncRoutes, anyRoutes)
   // 给路由器添加新路由
   router.addRoutes(state.resultAllRoutes)
  }
};

const actions = {
  // 用户登录
  async login({ commit }, userInfo) {
    console.log("login");
    
    const { username, password } = userInfo
    const result = await loginUser({
      username: username.trim(),
      password: password
    });
    console.log("result：",result);
    
    if (result.code == 20000) {
      console.log("result.code");
      
      commit("SET_TOKEN", result.data.token)
      setToken(result.data.token)
      return "ok";
    } else {
      console.log("result：faile");
      return Promise.reject(new Error("faile"))
    }
  },

  // 获取用户信息
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token)
        .then((response) => {
          const { data } = response;
          // 获取用户信息：返回数据包含(用户名name, 用户头像avatar,routes[返回的标志：不同用户应该展示哪些菜单标记],roles[用户角色信息],buttons[按钮信息,按钮权限用的标记])
          if (!data) {
            return reject("Verification failed, please Login again.");
          }
          commit("SET_USERINFO", data);
          commit("SET_RESULTASYNCROUTES", computedAsyncRoutes(asyncRoutes, data.routes));
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

  // 退出登录
  async logout({ commit, state }) {
    const result = await logout(state.token);
    if (result.code === 20000) {
      removeToken(); // must remove  token  first
      resetRouter();
      commit("RESET_STATE");
      return 'ok';
    } else {
      return Promise.reject(new Error("faile"));
    }
  },

  // remove token
  resetToken({ commit }) {
    return new Promise((resolve) => {
      removeToken(); // must remove  token  first
      commit("RESET_STATE");
      resolve();
    });
  },
};

// 定义一个函数，两个数组进行对比,对比出当前用户到底显示哪一些路由
const computedAsyncRoutes = (asyncRoutes, routes)=>{
  // 过滤出当前用户需要展示的异步路由
  return asyncRoutes.filter(item => {
    if(routes.indexOf(item.name) != -1) {
      // 服务器返回的信息包含这个元素
      // 递归: 对比二级极其以上的路由
      if(item.children && item.children.length) {
        item.children = computedAsyncRoutes(item.children, routes)
      }
      return true
    } 
  })
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
